package com.nutrition.health.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.nutrition.health.service.KimiAIService;
import com.nutrition.health.util.JsonUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Service
public class KimiAIServiceImpl implements KimiAIService {

    private static final Logger logger = LoggerFactory.getLogger(KimiAIServiceImpl.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Value("${app.kimi.api-key}")
    private String apiKey;

    @Value("${app.kimi.api-url}")
    private String apiUrl;

    @Value("${app.kimi.files-api-url}")
    private String filesApiUrl;

    @Value("${app.kimi.chat-api-url}")
    private String chatApiUrl;

    private String promptTemplate;

    public KimiAIServiceImpl() {
        try {
            // 从资源文件中加载提示词模板
            ClassPathResource resource = new ClassPathResource("aiPrompt");
            promptTemplate = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            logger.error("Failed to load prompt template", e);
            promptTemplate = "请分析这张食品图片，提供食品名称、类别和营养成分信息。";
        }
    }

    @Override
    public Map<String, Object> analyzeFoodImage(MultipartFile image) {
        try {
            logger.info("Starting food image analysis with Kimi API");

            // 1. 上传图片文件到 Kimi API
            String fileId = uploadFile(image);
            logger.info("File uploaded successfully, fileId: {}", fileId);

            // 2. 获取文件内容
            String fileContent = getFileContent(fileId);
            logger.info("File content retrieved");

            // 3. 调用 Kimi Chat API 分析图片内容
            String analysisResult = callKimiChatAPI(fileContent);
            logger.info("Analysis completed");

            // 4. 解析分析结果
            Map<String, Object> result = parseAnalysisResult(analysisResult);

            // 5. 添加图片信息
            try {
                // 处理图片，生成缩略图
                BufferedImage originalImage = ImageIO.read(image.getInputStream());
                BufferedImage thumbnail = resizeImage(originalImage, 200, 200);

                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                ImageIO.write(thumbnail, "jpeg", outputStream);
                byte[] thumbnailBytes = outputStream.toByteArray();

                // 将缩略图转换为 Base64 编码，用于前端显示
                String thumbnailBase64 = "data:image/jpeg;base64," + java.util.Base64.getEncoder().encodeToString(thumbnailBytes);
                result.put("imageUrl", thumbnailBase64);
            } catch (Exception e) {
                logger.warn("Failed to process image thumbnail", e);
            }

            return result;
        } catch (Exception e) {
            logger.error("Failed to analyze food image", e);
            throw new RuntimeException("Failed to analyze food image: " + e.getMessage(), e);
        }
    }

    /**
     * 上传文件到 Kimi API
     * @param file 文件
     * @return 文件ID
     */
    private String uploadFile(MultipartFile file) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost request = new HttpPost(filesApiUrl);
            request.setHeader("Authorization", "Bearer " + apiKey);

            // 构建 multipart 请求
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addBinaryBody("file", file.getInputStream(), ContentType.DEFAULT_BINARY, file.getOriginalFilename());
            builder.addTextBody("purpose", "file-extract", ContentType.TEXT_PLAIN);

            HttpEntity multipart = builder.build();
            request.setEntity(multipart);

            try (CloseableHttpResponse response = httpClient.execute(request)) {
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    String responseString = EntityUtils.toString(responseEntity);
                    JsonNode jsonResponse = objectMapper.readTree(responseString);

                    if (jsonResponse.has("id")) {
                        return jsonResponse.get("id").asText();
                    }

                    logger.error("Unexpected API response: {}", responseString);
                    throw new RuntimeException("Unexpected API response format");
                } else {
                    throw new RuntimeException("No response from Kimi API");
                }
            }
        }
    }

    /**
     * 获取文件内容
     * @param fileId 文件ID
     * @return 文件内容
     */
    private String getFileContent(String fileId) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet request = new HttpGet(filesApiUrl + "/" + fileId + "/content");
            request.setHeader("Authorization", "Bearer " + apiKey);

            try (CloseableHttpResponse response = httpClient.execute(request)) {
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    return EntityUtils.toString(responseEntity);
                } else {
                    throw new RuntimeException("No response from Kimi API");
                }
            }
        }
    }

    /**
     * 调用 Kimi Chat API 分析图片内容
     * @param fileContent 文件内容
     * @return 分析结果
     */
    private String callKimiChatAPI(String fileContent) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost request = new HttpPost(chatApiUrl);
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Authorization", "Bearer " + apiKey);

            // 构建请求体
            ObjectNode requestBody = objectMapper.createObjectNode();
            requestBody.put("model", "moonshot-v1-8k");
            requestBody.put("temperature", 0.3);
            requestBody.put("max_tokens", 2000);

            // 添加响应格式，要求返回 JSON
            ObjectNode responseFormat = objectMapper.createObjectNode();
            responseFormat.put("type", "json_object");
            requestBody.set("response_format", responseFormat);

            ArrayNode messages = objectMapper.createArrayNode();

            // 系统消息 - 添加格式要求和更详细的指导
            String enhancedPrompt = promptTemplate + "\n\n请以JSON格式返回分析结果，包含以下字段：\n" +
                "{\n" +
                "  \"name\": \"食品名称\",\n" +
                "  \"category\": \"食品类别\",\n" +
                "  \"calories\": 热量（kcal）,\n" +
                "  \"protein\": 蛋白质（g）,\n" +
                "  \"fat\": 脂肪（g）,\n" +
                "  \"carbs\": 碳水化合物（g）,\n" +
                "  \"fiber\": 膳食纤维（g）,\n" +
                "  \"vitamins\": {\n" +
                "    \"A\": \"含量\",\n" +
                "    \"C\": \"含量\"\n" +
                "  },\n" +
                "  \"minerals\": {\n" +
                "    \"钙\": \"含量\",\n" +
                "    \"铁\": \"含量\"\n" +
                "  },\n" +
                "  \"advice\": \"食用建议和注意事项\"\n" +
                "}\n\n" +
                "如果无法确定具体的营养成分数值，请提供合理的估计值。\n" +
                "如果完全无法识别食品，请提供一个通用的食品分析模板，并在advice字段中说明无法识别的原因。\n" +
                "请确保返回的是有效的JSON格式，不要包含任何额外的文本或解释。";

            ObjectNode systemMessage = objectMapper.createObjectNode();
            systemMessage.put("role", "system");
            systemMessage.put("content", enhancedPrompt);
            messages.add(systemMessage);

            // 系统消息 - 添加文件内容
            ObjectNode fileMessage = objectMapper.createObjectNode();
            fileMessage.put("role", "system");
            fileMessage.put("content", fileContent);
            messages.add(fileMessage);

            // 用户消息
            ObjectNode userMessage = objectMapper.createObjectNode();
            userMessage.put("role", "user");
            userMessage.put("content", "请分析这张食品图片中的食品成分和营养信息。");
            messages.add(userMessage);

            requestBody.set("messages", messages);

            StringEntity entity = new StringEntity(requestBody.toString(), "UTF-8");
            request.setEntity(entity);

            try (CloseableHttpResponse response = httpClient.execute(request)) {
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    String responseString = EntityUtils.toString(responseEntity);
                    logger.debug("API response: {}", responseString);

                    JsonNode jsonResponse = objectMapper.readTree(responseString);

                    if (jsonResponse.has("choices") && jsonResponse.get("choices").isArray() && jsonResponse.get("choices").size() > 0) {
                        JsonNode firstChoice = jsonResponse.get("choices").get(0);
                        if (firstChoice.has("message") && firstChoice.get("message").has("content")) {
                            return firstChoice.get("message").get("content").asText();
                        }
                    }

                    logger.error("Unexpected API response: {}", responseString);
                    throw new RuntimeException("Unexpected API response format");
                } else {
                    throw new RuntimeException("No response from Kimi API");
                }
            }
        }
    }

    /**
     * 解析分析结果
     * @param analysisResult 分析结果
     * @return 解析后的结果
     */
    private Map<String, Object> parseAnalysisResult(String analysisResult) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 尝试解析 JSON 格式的响应
            try {
                // 检查是否是 JSON 格式
                if (analysisResult.trim().startsWith("{") && analysisResult.trim().endsWith("}")) {
                    logger.info("Parsing JSON response");
                    // 使用 JsonUtils 解析 JSON
                    Map<String, Object> jsonResult = JsonUtils.fromJson(analysisResult);

                    // 提取基本信息
                    result.put("name", jsonResult.getOrDefault("name", "未知食品"));
                    result.put("category", jsonResult.getOrDefault("category", "未分类"));

                    // 提取数值信息，确保是数值类型
                    processNumericField(result, jsonResult, "calories");
                    processNumericField(result, jsonResult, "protein");
                    processNumericField(result, jsonResult, "fat");
                    processNumericField(result, jsonResult, "carbs");
                    processNumericField(result, jsonResult, "fiber");

                    // 处理维生素和矿物质
                    Object vitaminsObj = jsonResult.get("vitamins");
                    if (vitaminsObj instanceof Map) {
                        result.put("vitamins", vitaminsObj);
                    } else {
                        result.put("vitamins", new HashMap<String, String>());
                    }

                    Object mineralsObj = jsonResult.get("minerals");
                    if (mineralsObj instanceof Map) {
                        result.put("minerals", mineralsObj);
                    } else {
                        result.put("minerals", new HashMap<String, String>());
                    }

                    // 处理食用建议
                    result.put("advice", jsonResult.getOrDefault("advice", ""));

                    // 保存原始分析结果
                    result.put("fullAnalysis", analysisResult);

                    return result;
                }
            } catch (Exception e) {
                logger.warn("Failed to parse as JSON, falling back to default values: {}", e.getMessage());
            }

            // 如果 JSON 解析失败，使用默认值
            result.put("name", "未知食品");
            result.put("category", "未分类");
            result.put("calories", 0.0);
            result.put("protein", 0.0);
            result.put("fat", 0.0);
            result.put("carbs", 0.0);
            result.put("fiber", 0.0);
            result.put("vitamins", new HashMap<String, String>());
            result.put("minerals", new HashMap<String, String>());
            result.put("advice", "无法识别食品，请上传更清晰的图片。");
            result.put("fullAnalysis", analysisResult);

        } catch (Exception e) {
            logger.error("Failed to parse analysis result", e);
            result.put("error", "Failed to parse analysis result: " + e.getMessage());
        }

        return result;
    }

    /**
     * 处理数值字段
     * @param result 结果 Map
     * @param jsonResult JSON 结果 Map
     * @param fieldName 字段名
     */
    private void processNumericField(Map<String, Object> result, Map<String, Object> jsonResult, String fieldName) {
        Object value = jsonResult.get(fieldName);
        if (value != null) {
            if (value instanceof Number) {
                result.put(fieldName, ((Number) value).doubleValue());
            } else if (value instanceof String) {
                try {
                    result.put(fieldName, Double.parseDouble((String) value));
                } catch (NumberFormatException e) {
                    result.put(fieldName, 0.0);
                }
            } else {
                result.put(fieldName, 0.0);
            }
        } else {
            result.put(fieldName, 0.0);
        }
    }

    /**
     * 调整图片大小
     * @param originalImage 原始图片
     * @param maxWidth 最大宽度
     * @param maxHeight 最大高度
     * @return 调整后的图片
     */
    private BufferedImage resizeImage(BufferedImage originalImage, int maxWidth, int maxHeight) {
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();

        // 如果图片已经小于最大尺寸，不需要调整
        if (originalWidth <= maxWidth && originalHeight <= maxHeight) {
            return originalImage;
        }

        // 计算调整后的尺寸，保持宽高比
        float ratio = Math.min((float) maxWidth / originalWidth, (float) maxHeight / originalHeight);
        int newWidth = Math.round(originalWidth * ratio);
        int newHeight = Math.round(originalHeight * ratio);

        // 创建新图片
        BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        resizedImage.createGraphics().drawImage(originalImage.getScaledInstance(newWidth, newHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);

        return resizedImage;
    }
}